package com.caozf.io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * 创建时间：2019/11/2 18:56
 * 创建人:曹子方
 */
public class NIOServerSocketDemo {
    private  int port=8080;
    private Selector selector;
    public static void main(String[] args) {
        try {
            new NIOServerSocketDemo(8080).listen();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public NIOServerSocketDemo(int port) {
        try {
            this.port=port;
            ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(port));
            serverSocketChannel.configureBlocking(false);//非阻塞方式
            selector=Selector.open();
            serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);

        }catch (IOException e){
            e.printStackTrace();
        }
    }

    private void listen() throws IOException {
        while (true){
            selector.select();
            Set<SelectionKey> selectionKeys=selector.selectedKeys();
            Iterator<SelectionKey> iterator=selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey=iterator.next();
                process(selectionKey);
                iterator.remove();
            }
        }

    }

    private void process(SelectionKey selectionKey) throws IOException {
        if(selectionKey.isAcceptable()){
            ServerSocketChannel serverSocketChannel=(ServerSocketChannel)selectionKey.channel();
            SocketChannel socketChannel=serverSocketChannel.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector,SelectionKey.OP_READ);
        }else if(selectionKey.isReadable()){
            SocketChannel socketChannel =(SocketChannel)selectionKey.channel();
            ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
            int len=socketChannel.read(byteBuffer);
            if(len>0){
                byteBuffer.flip();
                System.out.println(byteBuffer.array().length);
                String content=new String(byteBuffer.array(),0,len);
                System.out.println("读取内容："+content);
                socketChannel.register(selector,SelectionKey.OP_WRITE).attach(content);
            }
        }else if(selectionKey.isWritable()){
            SocketChannel socketChannel=(SocketChannel) selectionKey.channel();
            String content=(String)selectionKey.attachment();
//            ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            socketChannel.write(ByteBuffer.wrap(("服务端返回:"+content).getBytes()));
            socketChannel.close();
        }
    }
}
